home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Magazin/MacEasy 11
/
Mac Magazin and MacEasy Magazine CD - Issue 11.iso
/
Sharewarebibliothek
/
Entwickler
/
WASTE 1.1b1 Distribution
/
WASTE Source
/
WEBirthDeath.p
< prev
next >
Wrap
Text File
|
1995-06-01
|
16KB
|
592 lines
unit WEBirthDeath;
{ WASTE PROJECT: }
{ Creation and Destruction, Standard Procs, etc. }
{ Copyright © 1993-1995 Marco Piovanelli }
{ All Rights Reserved }
interface
uses
WEHighLevelEditing;
function WENew (var destRect, viewRect: LongRect;
flags: Integer;
var hWE: WEHandle): OSErr;
procedure WEDispose (hWE: WEHandle);
function WEFeatureFlag (feature: Integer;
action: Integer;
hWE: WEHandle): Integer;
function WEGetInfo (selector: OSType;
info: Ptr;
hWE: WEHandle): OSErr;
function WESetInfo (selector: OSType;
info: Ptr;
hWE: WEHandle): OSErr;
implementation
uses
GestaltEqu, QDOffscreen, ToolUtils;
var
{ static variables }
_weStdDrawTextProc: WEDrawTextUPP;
_weStdPixelToCharProc: WEPixelToCharUPP;
_weStdCharToPixelProc: WECharToPixelUPP;
_weStdLineBreakProc: WELineBreakUPP;
_weStdWordBreakProc: WEWordBreakUPP;
_weStdCharByteProc: WECharByteUPP;
_weStdCharTypeProc: WECharTypeUPP;
procedure _WEStdDrawText (pText: Ptr;
textLength: LongInt;
slop: Fixed;
styleRunPosition: JustStyleCode;
hWE: WEHandle);
begin
DrawJustified(pText, textLength, slop, styleRunPosition, Point(kOneToOneScaling), Point(kOneToOneScaling));
end; { _WEStdDrawText }
function _WEStdPixelToChar (pText: Ptr;
textLength: LongInt;
slop: Fixed;
var width: Fixed;
var edge: SignedByte;
styleRunPosition: JustStyleCode;
hPos: Fixed;
hWE: WEHandle): LongInt;
var
tempPoint: Point;
lastWidth: Fixed;
begin
tempPoint := Point(kOneToOneScaling);
lastWidth := width;
_WEStdPixelToChar := PixelToChar(pText, textLength, slop, lastWidth, Boolean(edge), width, styleRunPosition, tempPoint, tempPoint);
{ round width to nearest integer value }
{ (this is supposed to fix an incompatibility with the WorldScript Power Adapter) }
width := BSL(FixRound(width), 16);
end; { _WEStdPixelToChar }
function _WEStdCharToPixel (pText: Ptr;
textLength: LongInt;
slop: Fixed;
offset: LongInt;
direction: Integer;
styleRunPosition: JustStyleCode;
hPos: LongInt;
hWE: WEHandle): Integer;
begin
_WEStdCharToPixel := CharToPixel(pText, textLength, slop, offset, direction, styleRunPosition, Point(kOneToOneScaling), Point(kOneToOneScaling));
end; { _WEStdCharToPixel }
function _WEStdLineBreak (pText: Ptr;
textLength: LongInt;
textStart, textEnd: LongInt;
var textWidth: Fixed;
var textOffset: LongInt;
hWE: WEHandle): StyledLineBreakCode;
begin
_WEStdLineBreak := StyledLineBreak(pText, textLength, textStart, textEnd, 0, textWidth, textOffset);
end; { _WEStdLineBreak }
procedure _WEStdWordBreak (pText: Ptr;
textLength: Integer;
offset: Integer;
edge: SignedByte;
var breakOffsets: OffsetTable;
script: ScriptCode;
hWE: WEHandle);
begin
FindWordBreaks(pText, textLength, offset, Boolean(edge), nil, breakOffsets, script);
end; { _WEStdWordBreak }
function _WEStdCharByte (pText: Ptr;
textOffset: Integer;
script: ScriptCode;
hWE: WEHandle): Integer;
begin
_WEStdCharByte := CharacterByteType(pText, textOffset, script);
end; { _WEStdCharByte }
function _WEStdCharType (pText: Ptr;
textOffset: Integer;
script: ScriptCode;
hWE: WEHandle): Integer;
begin
_WEStdCharType := CharacterType(pText, textOffset, script);
end; { _WEStdCharType }
function _WEScriptToFont (script: ScriptCode): Integer;
begin
{ given an explicit script code, return the first font ID in the corresponding range }
{ for an explanation of the formula given below, see IM: Text, page B-8 }
if (script = smRoman) then
_WEScriptToFont := 2
else if ((script > smRoman) and (script <= smUninterp)) then
_WEScriptToFont := $3E00 + $200 * script
else
_WEScriptToFont := systemFont; { unknown script code (?) }
end; { _WEScriptToFont }
{$IFC UNDEFINED SystemSevenFiveOrLater}
procedure _WEOldWordBreak (pText: Ptr;
textLength: Integer;
offset: Integer;
edge: SignedByte;
var breakOffsets: OffsetTable;
script: ScriptCode;
hWE: WEHandle);
var
savePort, tempPort: GrafPtr;
saveFont: Integer;
begin
{ the old (now obsolete) FindWord routine gets an implicit script parameter through }
{ the current graphics port txFont field, so first of all we must have a valid port }
GetPort(savePort);
tempPort := hWE^^.port;
SetPort(tempPort);
{ then set the txFont field to a font number in the specified script range }
saveFont := tempPort^.txFont;
TextFont(_WEScriptToFont(script));
{ call _FindWord }
FindWord(pText, textLength, offset, Boolean(edge), nil, breakOffsets);
{ restore font and port }
TextFont(saveFont);
SetPort(savePort);
end; { _WEOldWordBreak }
function _WEOldCharByte (pText: Ptr;
textOffset: Integer;
script: ScriptCode;
hWE: WEHandle): Integer;
var
savePort, tempPort: GrafPtr;
saveFont: Integer;
begin
{ the old (now obsolete) CharByte routine gets an implicit script parameter through }
{ the current graphics port txFont field, so first of all we must have a valid port }
GetPort(savePort);
tempPort := hWE^^.port;
SetPort(tempPort);
{ then set the txFont field to a font number in the specified script range }
saveFont := tempPort^.txFont;
TextFont(_WEScriptToFont(script));
{ call _CharByte }
_WEOldCharByte := CharByte(pText, textOffset);
{ restore font and port }
TextFont(saveFont);
SetPort(savePort);
end; { _WEOldCharByte }
function _WEOldCharType (pText: Ptr;
textOffset: Integer;
script: ScriptCode;
hWE: WEHandle): Integer;
var
savePort, tempPort: GrafPtr;
saveFont: Integer;
begin
{ the old (now obsolete) CharType routine gets an implicit script parameter through }
{ the current graphics port txFont field, so first of all we must have a valid port }
GetPort(savePort);
tempPort := hWE^^.port;
SetPort(tempPort);
{ then set the txFont field to a font number in the specified script range }
saveFont := tempPort^.txFont;
TextFont(_WEScriptToFont(script));
{ call _CharType }
_WEOldCharType := CharType(pText, textOffset);
{ restore font and port }
TextFont(saveFont);
SetPort(savePort);
end; { _WEOldCharType }
{$ENDC}
function _WERegisterWithTSM (hWE: WEHandle): OSErr;
{ the WE record must be already locked }
label
1;
var
pWE: WEPtr;
typeList: InterfaceTypeList;
err: OSErr;
begin
pWE := hWE^;
{ do nothing if the Text Services Manager isn't available }
if BTST(pWE^.flags, weFHasTextServices) then
begin
typeList[0] := kTextService;
err := NewTSMDocument(1, typeList, pWE^.tsmReference, LongInt(hWE));
if (err <> noErr) then
{ we don't consider it an error if our client application isn't TSM-aware }
if (err <> tsmNeverRegisteredErr) then
goto 1;
end;
{ clear result code }
err := noErr;
1:
{ return result code }
_WERegisterWithTSM := err;
end; { _WERegisterWithTSM }
procedure _WESetStandardHooks (hWE: WEHandle);
var
pWE: WEPtr;
begin
{ the first time we're called, create routine descriptors }
if (_weStdDrawTextProc = nil) then
begin
_weStdDrawTextProc := NewWEDrawTextProc(@_WEStdDrawText);
_weStdPixelToCharProc := NewWEPixelToCharProc(@_WEStdPixelToChar);
_weStdCharToPixelProc := NewWECharToPixelProc(@_WEStdCharToPixel);
_weStdLineBreakProc := NewWELineBreakProc(@_WEStdLineBreak);
{$IFC UNDEFINED SystemSevenFiveOrLater}
if (GetScriptManagerVariable(smVersion) < $710) then
begin
{ pre-7.1 version of the Script Manager: must use old hooks }
_weStdWordBreakProc := NewWEWordBreakProc(@_WEOldWordBreak);
_weStdCharByteProc := NewWECharByteProc(@_WEOldCharByte);
_weStdCharTypeProc := NewWECharTypeProc(@_WEOldCharType);
end
else
{$ENDC}
begin
{ Script Manager version 7.1 or newer }
_weStdWordBreakProc := NewWEWordBreakProc(@_WEStdWordBreak);
_weStdCharByteProc := NewWECharByteProc(@_WEStdCharByte);
_weStdCharTypeProc := NewWECharTypeProc(@_WEStdCharType);
end;
end; { if called for the first time }
{ replace null hook fields with the addresses of the standard hooks }
pWE := hWE^;
if (pWE^.drawTextHook = nil) then
pWE^.drawTextHook := _weStdDrawTextProc;
if (pWE^.pixelToCharHook = nil) then
pWE^.pixelToCharHook := _weStdPixelToCharProc;
if (pWE^.charToPixelHook = nil) then
pWE^.charToPixelHook := _weStdCharToPixelProc;
if (pWE^.lineBreakHook = nil) then
pWE^.lineBreakHook := _weStdLineBreakProc;
if (pWE^.wordBreakHook = nil) then
pWE^.wordBreakHook := _weStdWordBreakProc;
if (pWE^.charByteHook = nil) then
pWE^.charByteHook := _weStdCharByteProc;
if (pWE^.charTypeHook = nil) then
pWE^.charTypeHook := _weStdCharTypeProc;
end; { _WESetStandardHooks }
function WENew (var destRect, viewRect: LongRect;
flags: Integer;
var hWE: WEHandle): OSErr;
label
1, 2;
var
pWE: WEPtr;
allocFlags: Integer;
weFlags: LongInt;
response: LongInt;
r: Rect;
err: OSErr;
begin
pWE := nil;
weFlags := flags;
allocFlags := kAllocClear;
{ allocate the WE record }
err := _WEAllocate(SizeOf(WERec), allocFlags, hWE);
if (err <> noErr) then
goto 1;
{ lock it down }
HLock(Handle(hWE));
pWE := hWE^;
{ get active port }
GetPort(pWE^.port);
{ determine whether temporary memory should be used for data structures }
if BTST(weFlags, weFUseTempMem) then
allocFlags := allocFlags + kAllocTemp;
{ allocate the text handle (initially empty) }
err := _WEAllocate(0, allocFlags, pWE^.hText);
if (err <> noErr) then
goto 1;
{ allocate the line array }
err := _WEAllocate(2 * SizeOf(LineRec), allocFlags, pWE^.hLines);
if (err <> noErr) then
goto 1;
{ allocate the style table }
err := _WEAllocate(SizeOf(StyleTableElement), allocFlags, pWE^.hStyles);
if (err <> noErr) then
goto 1;
{ allocate the run array }
err := _WEAllocate(2 * SizeOf(RunArrayElement), allocFlags, pWE^.hRuns);
if (err <> noErr) then
goto 1;
{ check for the presence of various system software features }
{ determine whether Color QuickDraw is available }
if (Gestalt(gestaltQuickDrawVersion, response) = noErr) then
if (response >= gestalt8BitQD) then
BSET(weFlags, weFHasColorQD);
{ determine whether the Text Services manager is available }
if (Gestalt(gestaltTSMgrVersion, response) = noErr) then
BSET(weFlags, weFHasTextServices);
{ determine if there are any non-Roman scripts enabled }
if (GetScriptManagerVariable(smEnabled) > 1) then
BSET(weFlags, weFNonRoman);
{ determine whether a double-byte script is installed }
if (GetScriptManagerVariable(smDoubleByte) <> 0) then
BSET(weFlags, weFDoubleByte);
{ determine whether the Drag Manager is available }
if (Gestalt(gestaltDragMgrAttr, response) = noErr) then
if BTST(response, gestaltDragMgrPresent) then
BSET(weFlags, weFHasDragManager);
{ initialize miscellaneous fields of the WE record }
pWE^.nLines := 1;
pWE^.nStyles := 1;
pWE^.nRuns := 1;
pWE^.viewRect := viewRect;
pWE^.destRect := destRect;
pWE^.flags := weFlags;
pWE^.tsmAreaStart := kInvalidOffset;
pWE^.tsmAreaEnd := kInvalidOffset;
pWE^.dragCaretOffset := kInvalidOffset;
{ initialize hook fields with the addresses of the standard hooks }
_WESetStandardHooks(hWE);
{ create a region to hold the view rectangle }
pWE^.viewRgn := NewRgn;
WELongRectToRect(viewRect, r);
RectRgn(pWE^.viewRgn, r);
{ initialize the style run array }
with pWE^.hRuns^^[1] do
begin
runStart := 1;
styleIndex := -1;
end;
{ initialize the style table }
with pWE^.hStyles^^[0] do
begin
refCount := 1;
{ copy text attributes from the active graphics port }
info.runStyle.tsFont := pWE^.port^.txFont;
info.runStyle.tsSize := pWE^.port^.txSize;
info.runStyle.tsFace := GrafPtr1(pWE^.port)^.txFace;
if BTST(weFlags, weFHasColorQD) then
GetForeColor(info.runStyle.tsColor);
_WEFillFontInfo(pWE^.port, info);
end;
{ initialize the line array }
err := WECalText(hWE);
if (err <> noErr) then
goto 1;
{ register with the Text Services Manager }
err := _WERegisterWithTSM(hWE);
if (err <> noErr) then
goto 1;
{ unlock the WE record }
HUnlock(Handle(hWE));
{ clear result code }
err := noErr;
{ skip clean-up section }
goto 2;
1:
{ clean up }
if (pWE <> nil) then
begin
_WEForgetHandle(pWE^.hText);
_WEForgetHandle(pWE^.hLines);
_WEForgetHandle(pWE^.hStyles);
_WEForgetHandle(pWE^.hRuns);
if (pWE^.viewRgn <> nil) then
DisposeRgn(pWE^.viewRgn);
end;
_WEForgetHandle(hWE);
2:
{ return result code }
WENew := err;
end; { WENew }
procedure WEDispose (hWE: WEHandle);
var
pWE: WEPtr;
pTable: StyleTablePtr;
index: LongInt;
begin
{ sanity check: make sure WE isn't NIL }
if (hWE = nil) then
Exit(WEDispose);
{ lock the WE record }
HLock(Handle(hWE));
pWE := hWE^;
{ clear the Undo buffer }
WEClearUndo(hWE);
{ unregister with the Text Services Manager }
if (pWE^.tsmReference <> nil) then
begin
if (DeleteTSMDocument(pWE^.tsmReference) <> noErr) then
;
pWE^.tsmReference := nil;
end;
{ dispose of the offscreen graphics world }
if (pWE^.offscreenPort <> nil) then
begin
DisposeGWorld(GWorldPtr(pWE^.offscreenPort));
pWE^.offscreenPort := nil;
end;
if (pWE^.hStyles <> nil) then
begin
{ lock the style table }
HLock(Handle(pWE^.hStyles));
pTable := pWE^.hStyles^;
{ walk the style table, disposing of all embedded objects referenced there }
index := 0;
while (index < pWE^.nStyles) do
with pTable^[index] do
begin
if (refCount > 0) then
if (_WEFreeObject(WEObjectDescHandle(info.runStyle.tsObject)) <> noErr) then
; { don't known what to do with errors }
index := index + 1;
end;
end;
{ dispose of auxiliary data structures }
_WEForgetHandle(pWE^.hText);
_WEForgetHandle(pWE^.hLines);
_WEForgetHandle(pWE^.hStyles);
_WEForgetHandle(pWE^.hRuns);
_WEForgetHandle(pWE^.hObjectHandlerTable);
DisposeRgn(pWE^.viewRgn);
{ dispose of the WE record }
DisposeHandle(Handle(hWE));
end; { WEDispose }
function WEFeatureFlag (feature: Integer;
action: Integer;
hWE: WEHandle): Integer;
var
flag: Integer;
pWE: WEPtr;
begin
pWE := hWE^;
{ get current status of the specified flag }
flag := Integer(BTST(pWE^.flags, feature));
{ if action is weBitToggle, invert flag }
if (action = weBitToggle) then
action := 1 - flag;
{ reset flag according to action }
if (action = weBitClear) then
BCLR(pWE^.flags, feature)
else if (action = weBitSet) then
BSET(pWE^.flags, feature);
{ return old status }
WEFeatureFlag := flag;
end; { WEFeatureFlag }
function WEGetInfo (selector: OSType;
info: Ptr;
hWE: WEHandle): OSErr;
begin
WEGetInfo := _WEGetField(_WEMainSelectorTable, selector, info, hWE^);
end; { WEGetInfo }
function WESetInfo (selector: OSType;
info: Ptr;
hWE: WEHandle): OSErr;
begin
WESetInfo := _WESetField(_WEMainSelectorTable, selector, info, hWE^);
{ the hook fields can never be NIL, so replace any NIL field with the default address }
_WESetStandardHooks(hWE);
end; { WESetInfo }
end.